package com.iqiyi.pps.epg.core.dao.push;

import com.iqiyi.pps.epg.core.dao.base.HibernateDao;
import com.iqiyi.pps.epg.core.jdbc.ConnectionDB;
import com.iqiyi.pps.epg.core.model.push.AutoPushMsg;
import com.iqiyi.pps.epg.core.utils.DateTimeUtil;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Restrictions;
import org.hibernate.jdbc.Work;
import org.springframework.stereotype.Component;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

/**
 * Created by zhang on 2016/1/27.
 */
@Component
public class AutoPushMsgDao extends HibernateDao<AutoPushMsg, Long> {

    public void saveBatchJDBC(List<AutoPushMsg> saveList) {
        StringBuffer insertSql = new StringBuffer("insert into auto_push_msg(episode_id,device_id,passport_agent_type,platform_type,app_id,agent_type,epg_play_platform,push_time,push_status,msg_type,created_time) values");
        ConnectionDB connectionDB = new ConnectionDB();

        for (Iterator<AutoPushMsg> it = saveList.iterator(); it.hasNext();) {
            AutoPushMsg autoPushMsg = it.next();
            insertSql.append("(")
                    .append(autoPushMsg.getEpisodeId())
                    .append(",'")
                    .append(autoPushMsg.getDeviceId())
                    .append("',")
                    .append(autoPushMsg.getPassportAgentType())
                    .append(",")
                    .append(autoPushMsg.getPlatformType())
                    .append(",")
                    .append(autoPushMsg.getAppId())
                    .append(",")
                    .append(autoPushMsg.getAgentType())
                    .append(",")
                    .append(autoPushMsg.getEpgPlayPlatform())
                    .append(",'")
                    .append(DateTimeUtil.transLongFormat(autoPushMsg.getPushTime().getTime()))
                    .append("',")
                    .append(autoPushMsg.getPushStatus())
                    .append(",")
                    .append(autoPushMsg.getMsgType())
                    .append(",'")
                    .append(DateTimeUtil.transLongFormat(autoPushMsg.getCreatedTime().getTime()))
                    .append("')");
            if (it.hasNext()) {
                insertSql.append(",");
            }
        }

        connectionDB.executeUpdate(insertSql.toString());
    }

    public void saveBatch(final List<AutoPushMsg> saveList) {
        final String insertSql = "insert into auto_push_msg(episode_id,device_id,passport_agent_type,platform_type,app_id,agent_type,epg_play_platform,push_time,push_status,msg_type,created_time) values(?,?,?,?,?,?,?,?,?,?,?)";
        Session session = getSession();
        try {
            session.beginTransaction();
            session.doWork(new Work() {
                @Override
                public void execute(Connection connection) throws SQLException {
                    PreparedStatement stmt = connection.prepareStatement(insertSql);
                    try {
                        for (AutoPushMsg autoPushMsg : saveList) {
                            stmt.setLong(1, autoPushMsg.getEpisodeId());
                            stmt.setString(2, autoPushMsg.getDeviceId());
                            stmt.setInt(3, autoPushMsg.getPassportAgentType());
                            stmt.setInt(4, autoPushMsg.getPlatformType());
                            stmt.setInt(5, autoPushMsg.getAppId());
                            stmt.setInt(6, autoPushMsg.getAgentType());
                            stmt.setInt(7, autoPushMsg.getEpgPlayPlatform());
                            stmt.setTimestamp(8, autoPushMsg.getPushTime());
                            stmt.setInt(9, autoPushMsg.getPushStatus());
                            stmt.setInt(10, autoPushMsg.getMsgType());
                            stmt.setTimestamp(11, autoPushMsg.getCreatedTime());
                            stmt.addBatch();
                        }
                        stmt.executeBatch();
                    } finally {
                        try {
                            if (stmt != null) {
                                stmt.close();
                                stmt = null;
                            }
                        } catch (Exception e) {
                            stmt = null;
                            logger.error(e.getMessage());
                        }
                    }
                }
            });
            session.getTransaction().commit();
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
    }

    public boolean find(Long episodeId) {
        Criteria filters = createCriteria();
        filters.add(Restrictions.eq("episodeId", episodeId));
        filters.setMaxResults(1);
        List list = find(filters);
        if (list != null && list.size() > 0) {
            return true;
        } else {
            return false;
        }
    }

    public boolean findEffective(Long episodeId, Date currentTime) {
        Criteria filters = createCriteria();
        filters.add(Restrictions.eq("episodeId", episodeId));
        filters.add(Restrictions.ne("pushStatus", AutoPushMsg.AUTO_PUSH_STATUS_DEL));
        filters.add(Restrictions.ge("pushTime", currentTime));
        filters.setMaxResults(1);
        List list = find(filters);
        if (list != null && list.size() > 0) {
            return true;
        } else {
            return false;
        }
    }

    public List<AutoPushMsg> getPushMsg(long startTime, long endTime, int start, int max) {
        StringBuffer sb = new StringBuffer();
        sb.append("select {pushMsg.*} from auto_push_msg pushMsg LEFT JOIN program_platform_control control on pushMsg.episode_id = control.program_id ")
                .append("where pushMsg.push_time >= ? and pushMsg.push_time <=? and pushMsg.push_status = 0 ")
                .append("and pushMsg.epg_play_platform = control.play_platform and control.available_status = 1 ")
                .append("order by pushMsg.episode_id,pushMsg.app_id,pushMsg.platform_type,pushMsg.push_time asc");
        List<AutoPushMsg> list = getSession().createSQLQuery(sb.toString())
                .addEntity("pushMsg", AutoPushMsg.class)
                .setTimestamp(0, new Timestamp(startTime))
                .setTimestamp(1, new Timestamp(endTime))
                .setFirstResult(start)
                .setMaxResults(max)
                .list();
        return list;
    }

    public List<AutoPushMsg> getPushMsg(long maxTime, int start, int max) {
        StringBuffer sb = new StringBuffer();
        sb.append("select {pushMsg.*} from auto_push_msg pushMsg LEFT JOIN program_platform_control control on pushMsg.episode_id = control.program_id ")
                .append("where pushMsg.push_time <= ? and pushMsg.push_status = 0 ")
                .append("and pushMsg.epg_play_platform = control.play_platform and control.available_status = 1 ")
                .append("order by pushMsg.episode_id,pushMsg.app_id,pushMsg.platform_type,pushMsg.push_time asc");
        List<AutoPushMsg> list = getSession().createSQLQuery(sb.toString())
                .addEntity("pushMsg", AutoPushMsg.class)
                .setTimestamp(0, new Timestamp(maxTime))
                .setFirstResult(start)
                .setMaxResults(max)
                .list();
        return list;
    }

    public int updatePushStatusByPushTime(long startTime, long endTime, int updateStatus) {
        StringBuffer sb = new StringBuffer();
        sb.append("update auto_push_msg pushMsg,program_platform_control control set push_status = ? ")
                .append("where pushMsg.push_time >= ? and pushMsg.push_time <= ? ")
                .append("and pushMsg.episode_id = control.program_id ")
                .append("and pushMsg.push_status = 0 ")
                .append("and control.available_status = 0");
        int result = getSession().createSQLQuery(sb.toString())
                .setInteger(0, updateStatus)
                .setTimestamp(1, new Timestamp(startTime))
                .setTimestamp(2, new Timestamp(endTime))
                .executeUpdate();
        return result;
    }

    public int updatePushStatusByPushTime(long maxTime, int max, int status, int updateStatus) {
        int result = 0;
        Session session = getSession();
        Transaction transaction = session.beginTransaction();
        try {

            StringBuffer sb = new StringBuffer();
            sb.append("update auto_push_msg set push_status = ? ")
                    .append("where push_time <= ? ")
                    .append("and push_status = ?");

            result = session.createSQLQuery(sb.toString())
                    .setInteger(0, updateStatus)
                    .setTimestamp(1, new Timestamp(maxTime))
                    .setInteger(2, status)
                    .setMaxResults(max)
                    .executeUpdate();
            transaction.commit();
        } catch (Exception e) {
            logger.error(e.getMessage());
            transaction.rollback();
        }

        return result;
    }

    public int updatePushStatusById(long id, int updateStatus) {
        StringBuffer hql = new StringBuffer();
        hql.append("update AutoPushMsg set pushStatus = ? ")
                .append("where id = ?");
        return createQuery(hql.toString())
                .setInteger(0, updateStatus)
                .setLong(1, id)
                .executeUpdate();
    }

    public int updateJDBCPushStatusByIds(String ids, int updateStatus) {
        StringBuffer sql = new StringBuffer();
        sql.append("update auto_push_msg set push_status =").append(updateStatus).append(" where id in (").append(ids).append(")");
        ConnectionDB db = new ConnectionDB();
        return db.executeUpdate(sql.toString());
    }

    public int updatePushStatusByEpisodeId(long episodeId, int updateStatus) {
        StringBuffer hql = new StringBuffer();
        hql.append("update AutoPushMsg set pushStatus = ? ")
                .append("where episodeId = ?");
        return createQuery(hql.toString())
                .setInteger(0, updateStatus)
                .setLong(1, episodeId)
                .executeUpdate();
    }

    public int updatePushTimeByEpisodeId(long episodeId, int platformType, long pushTime) {
        StringBuffer hql = new StringBuffer();
        hql.append("update AutoPushMsg set pushTime = ? ")
                .append("where episodeId = ? and platformType = ?");
        return createQuery(hql.toString())
                .setTimestamp(0, new Timestamp(pushTime))
                .setLong(1, episodeId)
                .setInteger(2, platformType)
                .executeUpdate();
    }

    public int updatePushMsgById(String ids, AutoPushMsg autoPushMsg) {
        String appVer = autoPushMsg.getAppVer();
        int agentType = autoPushMsg.getAgentType();
        String msgId = autoPushMsg.getMsgId();
        int msgType = autoPushMsg.getMsgType();
        int duration = autoPushMsg.getDuration();
        String msgTitle = autoPushMsg.getMsgTitle();
        String msgContent = autoPushMsg.getMsgContent();
        String msgUrl = autoPushMsg.getMsgUrl();
        String msgAlertBody = autoPushMsg.getMsgAlertBody();
        String msgExt = autoPushMsg.getMsgExt();
        int priority = autoPushMsg.getPriority();
        String sign = autoPushMsg.getSign();
        int pushStatus = autoPushMsg.getPushStatus();
        String pushResponse = autoPushMsg.getPushResponse();
        Timestamp pushFinishTime = autoPushMsg.getPushFinishTime();

        StringBuffer hql = new StringBuffer();
        hql.append("update AutoPushMsg set appVer = ?, agentType = ?, msgId = ?, msgType = ?, duration = ?, msgTitle = ?, ")
                .append("msgContent = ?, msgUrl = ?, msgAlertBody = ?, msgExt = ?, priority = ?, sign = ?, pushStatus = ?, pushResponse = ?, pushFinishTime = ? ")
                .append("where id in (").append(ids).append(")");
        return createQuery(hql.toString())
                .setString(0, appVer)
                .setInteger(1, agentType)
                .setString(2, msgId)
                .setInteger(3, msgType)
                .setInteger(4, duration)
                .setString(5, msgTitle)
                .setString(6, msgContent)
                .setString(7, msgUrl)
                .setString(8, msgAlertBody)
                .setString(9, msgExt)
                .setInteger(10, priority)
                .setString(11, sign)
                .setInteger(12, pushStatus)
                .setString(13, pushResponse)
                .setTimestamp(14, pushFinishTime)
                .executeUpdate();
    }
}
